package com.ygqh.baby.service.impl;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.ygqh.baby.ao.Message;
import com.ygqh.baby.ao.OrderStatus;
import com.ygqh.baby.ao.PayType;
import com.ygqh.baby.ao.QueryInfo;
import com.ygqh.baby.ao.ResultSet;
import com.ygqh.baby.mapper.ActionOrderMapper;
import com.ygqh.baby.mapper.ActionProductMapper;
import com.ygqh.baby.po.ActionOrder;
import com.ygqh.baby.po.ActionOrder.PickWay;
import com.ygqh.baby.po.ActionOrderExample;
import com.ygqh.baby.po.ActionProduct;
import com.ygqh.baby.service.ActionOrderService;

@Service
public class ActionOrderServiceImpl implements ActionOrderService {

	@Autowired
	private ActionOrderMapper actionOrderMapper;
	@Autowired
	private ActionProductMapper actionProductMapper;

	@Override
	public List<ActionOrder> find() {
		ActionOrderExample example = new ActionOrderExample();
		return actionOrderMapper.selectByExample(example);
	}

	@Override
	public int findCount() {
		ActionOrderExample example = new ActionOrderExample();
		return actionOrderMapper.countByExample(example);
	}

	@Override
	public ActionOrder findById(Long id) {
		return actionOrderMapper.selectByPrimaryKey(id);
	}

	@Override
	public int save(ActionOrder actionOrder) {
		boolean flag = true;
		if (PickWay.SinceLift.equals(actionOrder.getPickWay())) { // 自提扣库存
			int row = actionProductMapper.updateSkuStock(actionOrder.getActionId(), actionOrder.getSkuCode(), actionOrder.getAmount(), "reduce");
			if (row == 0) {
				flag = false;
			}
		}
		if (flag) {
			return actionOrderMapper.insertSelective(actionOrder);
		}
		return 0;
	}

	@Override
	public int update(ActionOrder actionOrder) {
		return actionOrderMapper.updateByPrimaryKeySelective(actionOrder);
	}

	@Override
	public ResultSet<ActionOrder> search(QueryInfo queryInfo, String q) {
		List<ActionOrder> list = actionOrderMapper.selectSuper(queryInfo, q);
		int count = actionOrderMapper.countSuper(q);
		ResultSet<ActionOrder> resultSet = new ResultSet<ActionOrder>(count, list);
		return resultSet;
	}

	@Override
	public int deleteSoft(Long[] ids) {
		Assert.notEmpty(ids);
		ActionOrderExample example = new ActionOrderExample();
		example.createCriteria().andIdIn(Arrays.asList(ids));
		ActionOrder record = new ActionOrder();

		return actionOrderMapper.updateByExampleSelective(record, example);
	}

	@Override
	public int deleteSoft(Long id) {
		return this.deleteSoft(new Long[] { id });
	}

	@Override
	public int saveOrUpdate(ActionOrder actionOrder) {
		int r = 0;
		if (actionOrder.getId() != null) {
			r = this.update(actionOrder);
		} else {
			r = this.save(actionOrder);
		}
		return r;
	}

	@Override
	public Map<String, Object> selectSalesReport(Long actionId, Date startDate, Date endDate) {
		List<Map<String, Object>> reportList = actionOrderMapper.selectSalesReportWithProductInfo(actionId, startDate, endDate);
		Map<String, Object> reportData = actionOrderMapper.selectSalesReportWithOrderInfo(actionId, startDate, endDate);
		if (reportData == null) {
			reportData = new HashMap<>();
			reportData.put("totalAmount", 0L);
			reportData.put("totalMoney", BigDecimal.ZERO);
		}
		reportData.put("reportList", reportList);
		return reportData;
	}

	@Override
	public List<Map<String, Object>> selectSalesReportALL(Long actionId) {
		return actionOrderMapper.selectSalesReportALL(actionId);
	}

	@Override
	public Message saveOrder(Long userId, List<ActionProduct> productList, BigDecimal totalPrice, PayType payType, OrderStatus orderStatus, PickWay pickWay,
			String remark) {
		Date now = new Date();
		Long time = now.getTime();
		payType = payType != null ? payType : PayType.WeChat;
		orderStatus = orderStatus != null ? orderStatus : OrderStatus.WaitingPay;
		for (ActionProduct product : productList) {
			ActionOrder order = new ActionOrder(product.getActionId(), time.toString(), userId, totalPrice, product.getSkuCode(), product.getProductName(),
					product.getSalesPrice(), product.getSize(), product.getProductAmount(), now, payType, orderStatus, pickWay, remark);
			int row = this.save(order);
			if (row <= 0) {
				return Message.error("提交订单失败，商品【" + product.getProductName() + " " + product.getShortName() + " " + product.getSize() + "】库存不足",
						product.getSkuCode());
			}
		}
		return Message.success(time.toString());
	}

	@Override
	public ActionOrder findByOrderId(String orderId) {
		return actionOrderMapper.selectByOrderId(orderId);
	}

	@Override
	public int updateOrderStatusByPaySuccess(String orderId) {
		return actionOrderMapper.updateOrderStatusByPaySuccess(orderId);
	}

	@Override
	public List<ActionOrder> findOrderListHasDetail(Long actionId, Long userId, OrderStatus orderStatus) {
		return actionOrderMapper.selectOrderList(actionId, userId, orderStatus == null ? null : orderStatus.name());
	}

	@Override
	public int updateOrderToClose(Long actionId, Date startDate, Date endDate) {
		List<ActionOrder> orderList = this.findOrderList(actionId, OrderStatus.WaitingPay, startDate, endDate);
		if (CollectionUtils.isEmpty(orderList)) {
			return 0;
		}
		Map<String, List<ActionOrder>> collect = orderList.stream().filter(o -> PickWay.SinceLift.equals(o.getPickWay()))
				.collect(Collectors.groupingBy(ActionOrder::getSkuCode)); // 自提订单返还库存
		for (Map.Entry<String, List<ActionOrder>> entry : collect.entrySet()) {
			Long amount = entry.getValue().stream().map(o -> o.getAmount()).reduce((a1, a2) -> (a1 + a2)).get();
			actionProductMapper.updateSkuStock(actionId, entry.getKey(), amount, "increase");
		}
		List<Long> idList = orderList.stream().map(o -> o.getId()).collect(Collectors.toList());
		return actionOrderMapper.updateOrderToClose(idList);
	}

	private List<ActionOrder> findOrderList(Long actionId, OrderStatus orderStatus, Date startDate, Date endDate) {
		ActionOrderExample example = new ActionOrderExample();
		ActionOrderExample.Criteria criteria = example.createCriteria();
		if (orderStatus != null) {
			criteria.andOrderStatusEqualTo(orderStatus.name());
		}
		if (startDate != null) {
			criteria.andCreateTimeGreaterThanOrEqualTo(startDate);
		}
		if (endDate != null) {
			criteria.andCreateTimeLessThan(endDate);
		}
		criteria.andActionIdEqualTo(actionId);
		return actionOrderMapper.selectByExample(example);
	}

}
